#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
IR 调试工具
提供打印和可视化 IR 节点结构的功能
"""

from typing import Any, Dict, List, Optional, Set, TextIO
import sys
from .base import IRNode
from ..symbol_table import TypeInfo


class IRDebugPrinter:
    """IR 调试打印器"""

    def __init__(self, output: TextIO = sys.stdout, indent_size: int = 2):
        """初始化调试打印器

        Args:
            output: 输出流，默认为标准输出
            indent_size: 缩进大小，默认为2个空格
        """
        self.output = output
        self.indent_size = indent_size
        self.visited_nodes: Set[int] = set()

    def print_node(
        self,
        node: IRNode,
        max_depth: Optional[int] = None,
        show_types: bool = True,
        show_extensions: bool = True,
    ) -> None:
        """打印单个 IR 节点及其子节点

        Args:
            node: 要打印的 IR 节点
            max_depth: 最大递归深度，None 表示无限制
            show_types: 是否显示类型信息
            show_extensions: 是否显示扩展参数
        """
        self.visited_nodes.clear()
        self._print_node_recursive(node, 0, max_depth, show_types, show_extensions)

    def print_tree(
        self,
        node: IRNode,
        max_depth: Optional[int] = None,
        show_types: bool = True,
        show_extensions: bool = False,
    ) -> None:
        """以树形结构打印 IR 节点

        Args:
            node: 根节点
            max_depth: 最大递归深度
            show_types: 是否显示类型信息
            show_extensions: 是否显示扩展参数
        """
        self.visited_nodes.clear()
        self._print_tree_recursive(node, [], max_depth, show_types, show_extensions)

    def print_summary(self, node: IRNode) -> None:
        """打印 IR 节点的摘要信息

        Args:
            node: 要分析的根节点
        """
        stats = self._collect_statistics(node)

        self.output.write("=== IR 节点统计摘要 ===\n")
        self.output.write(f"总节点数: {stats['total_nodes']}\n")
        self.output.write(f"最大深度: {stats['max_depth']}\n")
        self.output.write("\n节点类型分布:\n")

        for node_type, count in sorted(stats["node_types"].items()):
            self.output.write(f"  {node_type}: {count}\n")

        if stats["type_info_nodes"]:
            self.output.write(f"\n有类型信息的节点: {stats['type_info_nodes']}\n")

        if stats["extension_nodes"]:
            self.output.write(f"有扩展参数的节点: {stats['extension_nodes']}\n")

    def _print_node_recursive(
        self,
        node: IRNode,
        depth: int,
        max_depth: Optional[int],
        show_types: bool,
        show_extensions: bool,
    ) -> None:
        """递归打印节点"""
        if max_depth is not None and depth > max_depth:
            return

        node_id = id(node)
        if node_id in self.visited_nodes:
            self._write_indent(depth)
            self.output.write(f"<循环引用: {node.node_type}>\n")
            return

        self.visited_nodes.add(node_id)

        # 打印节点基本信息
        self._write_indent(depth)
        self.output.write(f"{node.node_type}")

        if hasattr(node, "name") and node.name:
            self.output.write(f" '{node.name}'")

        if hasattr(node, "source_line") and node.source_line:
            self.output.write(f" @{node.source_line}")

        # 显示类型信息
        if show_types:
            try:
                # 类型信息现在通过符号系统获取
                # TODO: 重构以使用符号系统
                type_info = None
                if type_info:
                    self.output.write(f" : {self._format_type_info(type_info)}")
            except Exception as e:
                self.output.write(f" : <类型错误: {e}>")

        self.output.write("\n")

        # 显示扩展参数
        if show_extensions and node.extension_params:
            for key, value in node.extension_params.items():
                self._write_indent(depth + 1)
                self.output.write(f"[{key}] = {self._format_value(value)}\n")

        # 递归打印子节点
        try:
            for child in node.get_child_nodes():
                self._print_node_recursive(
                    child, depth + 1, max_depth, show_types, show_extensions
                )
        except Exception as e:
            self._write_indent(depth + 1)
            self.output.write(f"<子节点遍历错误: {e}>\n")

    def _print_tree_recursive(
        self,
        node: IRNode,
        prefixes: List[str],
        max_depth: Optional[int],
        show_types: bool,
        show_extensions: bool,
    ) -> None:
        """以树形结构递归打印节点"""
        if max_depth is not None and len(prefixes) > max_depth:
            return

        node_id = id(node)
        if node_id in self.visited_nodes:
            self.output.write("".join(prefixes) + "<循环引用>\n")
            return

        self.visited_nodes.add(node_id)

        # 打印当前节点
        self.output.write("".join(prefixes))

        node_info = node.node_type
        if hasattr(node, "name") and node.name:
            node_info += f" '{node.name}'"

        if show_types:
            try:
                # 类型信息现在通过符号系统获取
                # TODO: 重构以使用符号系统
                type_info = None
                if type_info:
                    node_info += f" : {self._format_type_info(type_info)}"
            except Exception:
                pass

        self.output.write(node_info + "\n")

        # 显示扩展参数
        if show_extensions and node.extension_params:
            for i, (key, value) in enumerate(node.extension_params.items()):
                is_last_ext = i == len(node.extension_params) - 1
                ext_prefix = "└── " if is_last_ext else "├── "
                self.output.write(
                    "".join(prefixes)
                    + "    "
                    + ext_prefix
                    + f"[{key}] = {self._format_value(value)}\n"
                )

        # 递归打印子节点
        try:
            children = list(node.get_child_nodes())
            for i, child in enumerate(children):
                is_last = i == len(children) - 1
                if is_last:
                    new_prefixes = prefixes + ["└── ", "    "]
                else:
                    new_prefixes = prefixes + ["├── ", "│   "]

                self._print_tree_recursive(
                    child, new_prefixes, max_depth, show_types, show_extensions
                )
        except Exception as e:
            self.output.write("".join(prefixes) + f"<子节点遍历错误: {e}>\n")

    def _collect_statistics(self, node: IRNode) -> Dict[str, Any]:
        """收集 IR 树的统计信息"""
        stats = {
            "total_nodes": 0,
            "max_depth": 0,
            "node_types": {},
            "type_info_nodes": 0,
            "extension_nodes": 0,
        }

        def collect_recursive(n: IRNode, depth: int) -> None:
            stats["total_nodes"] += 1
            stats["max_depth"] = max(stats["max_depth"], depth)

            # 统计节点类型
            node_type = n.node_type or "unknown"
            stats["node_types"][node_type] = stats["node_types"].get(node_type, 0) + 1

            # 统计有类型信息的节点
            # 类型信息现在通过符号系统获取
            # TODO: 重构以使用符号系统
            if False:  # 临时禁用类型检查
                stats["type_info_nodes"] += 1

            # 统计有扩展参数的节点
            if n.extension_params:
                stats["extension_nodes"] += 1

            # 递归处理子节点
            try:
                for child in n.get_child_nodes():
                    collect_recursive(child, depth + 1)
            except Exception:
                pass

        collect_recursive(node, 0)
        return stats

    def _write_indent(self, depth: int) -> None:
        """写入缩进"""
        self.output.write(" " * (depth * self.indent_size))

    def _format_type_info(self, type_info: TypeInfo) -> str:
        """格式化类型信息"""
        if not type_info:
            return "None"

        result = type_info.name
        if type_info.args:
            args_str = ", ".join(self._format_type_info(arg) for arg in type_info.args)
            result += f"[{args_str}]"

        return result

    def _format_value(self, value: Any) -> str:
        """格式化值用于显示"""
        if isinstance(value, str):
            return f"'{value}'"
        elif isinstance(value, (list, tuple)):
            if len(value) > 3:
                return f"[{len(value)} items]"
            else:
                return str(value)
        elif isinstance(value, dict):
            if len(value) > 3:
                return f"{{{len(value)} items}}"
            else:
                return str(value)
        else:
            return str(value)


# 便捷函数
def print_ir_node(
    node: IRNode,
    max_depth: Optional[int] = None,
    show_types: bool = True,
    show_extensions: bool = True,
    output: TextIO = sys.stdout,
) -> None:
    """打印 IR 节点的详细信息

    Args:
        node: 要打印的 IR 节点
        max_depth: 最大递归深度
        show_types: 是否显示类型信息
        show_extensions: 是否显示扩展参数
        output: 输出流
    """
    printer = IRDebugPrinter(output)
    printer.print_node(node, max_depth, show_types, show_extensions)


def print_ir_tree(
    node: IRNode,
    max_depth: Optional[int] = None,
    show_types: bool = True,
    show_extensions: bool = False,
    output: TextIO = sys.stdout,
) -> None:
    """以树形结构打印 IR 节点

    Args:
        node: 根节点
        max_depth: 最大递归深度
        show_types: 是否显示类型信息
        show_extensions: 是否显示扩展参数
        output: 输出流
    """
    printer = IRDebugPrinter(output)
    printer.print_tree(node, max_depth, show_types, show_extensions)


def print_ir_summary(node: IRNode, output: TextIO = sys.stdout) -> None:
    """打印 IR 节点的统计摘要

    Args:
        node: 要分析的根节点
        output: 输出流
    """
    printer = IRDebugPrinter(output)
    printer.print_summary(node)


def debug_ir_node(node: IRNode, mode: str = "tree", **kwargs) -> None:
    """调试 IR 节点的通用接口

    Args:
        node: 要调试的 IR 节点
        mode: 调试模式，可选 "tree", "detail", "summary"
        **kwargs: 其他参数传递给具体的打印函数
    """
    if mode == "tree":
        print_ir_tree(node, **kwargs)
    elif mode == "detail":
        print_ir_node(node, **kwargs)
    elif mode == "summary":
        print_ir_summary(node, **kwargs)
    else:
        raise ValueError(f"不支持的调试模式: {mode}")
